package com.yh.search.service;

import com.alibaba.fastjson.JSON;
import com.lxw.framework.domain.course.CoursePub;
import com.lxw.framework.domain.course.TeachplanMediaPub;
import com.lxw.framework.domain.search.CourseSearchParam;
import com.lxw.framework.exception.CustomException;
import com.lxw.framework.model.response.CommonCode;
import com.lxw.framework.model.response.QueryResponseResult;
import com.lxw.framework.model.response.QueryResult;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class EsSearchServiceImpl implements EsSearchService {
    @Autowired
    RestHighLevelClient restHighLevelClient;
    @Value("${yh.course.index}")
    private String index;
    @Value("${yh.course.type}")
    private String type;

    @Override
    public QueryResponseResult list(int page, int size, CourseSearchParam courseSearchParam) {
        try {
            SearchRequest searchRequest = new SearchRequest("yh_course");
            searchRequest.types("doc");
            String keyword = courseSearchParam.getKeyword();

            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
            if (StringUtils.isNotEmpty(keyword)) {
                MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keyword, "name", "description", "teachplan");
                multiMatchQueryBuilder.field("name", 10);
                boolQueryBuilder.must(multiMatchQueryBuilder);
            }
            if (StringUtils.isNotEmpty(courseSearchParam.getSt())) {
                boolQueryBuilder.filter(QueryBuilders.termQuery("st", courseSearchParam.getSt()));
            }
            if (StringUtils.isNotEmpty(courseSearchParam.getMt())) {
                boolQueryBuilder.filter(QueryBuilders.termQuery("mt", courseSearchParam.getMt()));
            }
            if (StringUtils.isNotEmpty(courseSearchParam.getGrade())) {
                boolQueryBuilder.filter(QueryBuilders.termQuery("grade", courseSearchParam.getGrade()));
            }

            // 高亮处理
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            highlightBuilder.preTags("<font style=\"color:red\">");
            highlightBuilder.postTags("</font>");
            highlightBuilder.field("name");
            searchSourceBuilder.highlighter(highlightBuilder);

            searchSourceBuilder.query(boolQueryBuilder);

            // 执行分页
            if (page < 1) {
                page = 1;
            }
            searchSourceBuilder.from((page - 1) * size);
            searchSourceBuilder.size(size);


            // 执行es搜索
            searchRequest.source(searchSourceBuilder);
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            // 获取搜索结果
            SearchHit[] hits = search.getHits().getHits();
            long total = search.getHits().getTotalHits();
            List<CoursePub> coursePubList = new ArrayList<>();

            for (SearchHit hit : hits) {
                // 获取JSON结果字符串
                String sourceAsString = hit.getSourceAsString();
                // json字符串解析成对象
                CoursePub coursePub = JSON.parseObject(sourceAsString, CoursePub.class);

                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                HighlightField highlightField = highlightFields.get("name");
                if (highlightField != null) {
                    Text[] fragments = highlightField.getFragments();
                    StringBuilder stringBuilder = new StringBuilder();
                    for (Text text : fragments) {
                        stringBuilder.append(text.string());
                    }
                    coursePub.setName(stringBuilder.toString());
                }


                coursePubList.add(coursePub);
            }

            QueryResult<CoursePub> queryResult = new QueryResult();
            queryResult.setList(coursePubList);
            queryResult.setTotal(total);
            return new QueryResponseResult(CommonCode.SUCCESS, queryResult);
        } catch (IOException e) {
            e.printStackTrace();
            throw new CustomException(CommonCode.FAIL);
        }
    }

    @Override
    public Map<String, CoursePub> getall(String id) {
        try {
            SearchRequest searchRequest = new SearchRequest("yh_course");
            searchRequest.types("doc");

            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

            boolQueryBuilder.filter(QueryBuilders.termQuery("id", id));
            searchSourceBuilder.query(boolQueryBuilder);

            // 执行es搜索
            searchRequest.source(searchSourceBuilder);
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            // 获取搜索结果
            SearchHit[] hits = search.getHits().getHits();
            long total = search.getHits().getTotalHits();
            if(hits==null||hits.length==0){
                return null;
            }
            SearchHit hit = hits[0];
            // 获取JSON结果字符串
            String sourceAsString = hit.getSourceAsString();
            // json字符串解析成对象
            CoursePub coursePub = JSON.parseObject(sourceAsString, CoursePub.class);

            Map<String,CoursePub> map = new HashMap<>();
            map.put(id,coursePub);
            return map;

        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public TeachplanMediaPub getmedia(String teachplanId) {
        try {
            SearchRequest searchRequest = new SearchRequest("yh_course_media");
            searchRequest.types("doc");

            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

            boolQueryBuilder.filter(QueryBuilders.termQuery("teachplan_id", teachplanId));
            searchSourceBuilder.query(boolQueryBuilder);

            // 执行es搜索
            searchRequest.source(searchSourceBuilder);
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            // 获取搜索结果
            SearchHit[] hits = search.getHits().getHits();
            long total = search.getHits().getTotalHits();
            if(hits==null||hits.length==0){
                return null;
            }
            SearchHit hit = hits[0];
            // 获取JSON结果字符串
            String sourceAsString = hit.getSourceAsString();
            // json字符串解析成对象
            TeachplanMediaPub teachplanMediaPub = JSON.parseObject(sourceAsString, TeachplanMediaPub.class);

            return teachplanMediaPub;

        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
